package org.kermeta.spem.activityautomation.eclipse.createemptyemfproject;

/**
 * <copyright>
 *
 * Copyright (c) 2005-2006 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: 
 *   IBM - Initial API and implementation
 *
 * </copyright>
 *
 * EmptyProjectWizard.java,v 1.1 2005/05/06 02:19:59 marcelop Exp
 */

import java.io.IOException;
import java.io.PrintStream;
import java.util.Collections;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
import org.eclipse.ui.part.ISetSelectionTarget;

import org.eclipse.emf.codegen.ecore.Generator;
import org.eclipse.emf.codegen.ecore.genmodel.provider.GenModelEditPlugin;
import org.eclipse.emf.codegen.util.CodeGenUtil;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;

import org.kermeta.spem.activityautomation.eclipse.createemptyemfproject.CreateEmptyEMFProject;
import org.kermeta.spem.executioncontext.ExecutionContext;
import org.kermeta.spem.executioncontext.ExecutioncontextFactory;
import org.kermeta.spem.executioncontext.ExecutioncontextPackage;
import org.kermeta.spem.executioncontext.Key;
import org.kermeta.spem.executioncontext.Value;
import org.kermeta.spem.processexecution.utils.model.ModelUtils;


/**
 * @since 2.1.0
 */
public class EmptyProjectWizard2 extends Wizard implements INewWizard
{
	protected IWorkbench workbench;
	protected IPath genModelProjectLocation;
	protected IPath genModelContainerPath;
	protected IProject project;
	protected String initialProjectName;
	private CreateEmptyEMFProject createEmptyEMFProject;
	private String contextModelPath;

	public EmptyProjectWizard2(CreateEmptyEMFProject createEmptyEMFProject, String contextModelPath){
		this.createEmptyEMFProject = createEmptyEMFProject;
		this.contextModelPath = contextModelPath;
	}

	public void init(IWorkbench workbench, IStructuredSelection selection)
	{
		this.workbench = workbench;
		setDefaultPageImageDescriptor(ExtendedImageRegistry.INSTANCE.getImageDescriptor(GenModelEditPlugin.INSTANCE.getImage("full/wizban/NewEmptyEMFProject")));
		setWindowTitle(GenModelEditPlugin.INSTANCE.getString("_UI_NewEmptyProject_title"));
	}

	@Override
	public void addPages()
	{
		WizardNewProjectCreationPage newProjectCreationPage = new WizardNewProjectCreationPage("NewProjectCreationPage")
		{
			@Override
			protected boolean validatePage()
			{
				if (super.validatePage())
				{
					IPath locationPath = getLocationPath();
					genModelProjectLocation = Platform.getLocation().equals(locationPath) ? null : locationPath;
					IPath projectPath = getProjectHandle().getFullPath();
					genModelContainerPath = projectPath.append("src");
					return true;
				}
				else
				{
					return false;
				}
			}
		};

		newProjectCreationPage.setInitialProjectName(initialProjectName);
		newProjectCreationPage.setTitle(GenModelEditPlugin.INSTANCE.getString("_UI_EmptyProject_title"));
		newProjectCreationPage.setDescription(GenModelEditPlugin.INSTANCE.getString("_UI_EmptyProject_description"));
		addPage(newProjectCreationPage);
	}



	@Override
	public boolean performFinish()
	{
		WorkspaceModifyOperation operation = new WorkspaceModifyOperation()
		{
			@Override
			protected void execute(IProgressMonitor progressMonitor)
			{
				try
				{
					System.out.println("genModelContainerPath = "+genModelContainerPath.toString());
					System.out.println("genModelProjectLocation = "+genModelProjectLocation);
					project = Generator.createEMFProject(
							new Path(genModelContainerPath.toString()),
							genModelProjectLocation,
							Collections.<IProject>emptyList(),
							progressMonitor,
							Generator.EMF_MODEL_PROJECT_STYLE | Generator.EMF_PLUGIN_PROJECT_STYLE);

					CodeGenUtil.EclipseUtil.findOrCreateContainer
					(new Path("/" + genModelContainerPath.segment(0) + "/model"), true, genModelProjectLocation, progressMonitor);

					createEmptyEMFProject.setModelContainer(CodeGenUtil.EclipseUtil.findOrCreateContainer
							(new Path("/" + genModelContainerPath.segment(0) + "/model"), true, genModelProjectLocation, progressMonitor));

					PrintStream manifest = 
							new PrintStream
							(URIConverter.INSTANCE.createOutputStream
									(URI.createPlatformResourceURI("/" + genModelContainerPath.segment(0) + "/META-INF/MANIFEST.MF", true), null),
									false, "UTF-8");
					manifest.println("Manifest-Version: 1.0");
					manifest.println("Bundle-ManifestVersion: 2");
					manifest.print("Bundle-Name: ");
					manifest.println(genModelContainerPath.segment(0));
					manifest.print("Bundle-SymbolicName: ");
					manifest.println(CodeGenUtil.validPluginID(genModelContainerPath.segment(0)));
					manifest.println("Bundle-Version: 0.1.0");
					manifest.println("Require-Bundle: org.eclipse.emf.ecore");
					manifest.close();
				}
				catch (Exception exception)
				{
					GenModelEditPlugin.INSTANCE.log(exception);
				}
				finally
				{
					progressMonitor.done();
				}
			}
		};

		try
		{
			getContainer().run(false, false, operation);
		}
		catch (Exception exception)
		{
			GenModelEditPlugin.INSTANCE.log(exception);
			return false;
		}

		if (project != null)
		{
			IWorkbenchPage page = workbench.getActiveWorkbenchWindow().getActivePage();
			final IWorkbenchPart activePart = page.getActivePart();
			if (activePart instanceof ISetSelectionTarget)
			{
				final ISelection targetSelection = new StructuredSelection(project);
				getShell().getDisplay().asyncExec(new Runnable()
				{
					public void run()
					{
						((ISetSelectionTarget)activePart).selectReveal(targetSelection);
					}
				});
			}
		}

		//Write the project name into the context model
		ExecutionContext executionContext = ModelUtils.getExecutionContextRoot(contextModelPath);
		ModelUtils.addKeyValueIntoExecutionContextModel(executionContext, "project name", project.getName());
//		// Initialize the model
//		ExecutioncontextPackage.eINSTANCE.eClass();
//
//		// Register the XMI resource factory for the .executioncontext extension
//
//		Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
//		Map<String, Object> m = reg.getExtensionToFactoryMap();
//		m.put("executioncontext", new XMIResourceFactoryImpl());
//
//		// Obtain a new resource set
//		ResourceSet resSet = new ResourceSetImpl();
//
//		// Get the resource
//		Resource resource = resSet.getResource(URI
//				.createURI(contextModelPath), true);
//		// Get the first model element and cast it to the right type, in my
//		// example everything is hierarchical included in this first node
//		ExecutionContext executionContext = (ExecutionContext) resource.getContents().get(0);
//		
//		Key key = ExecutioncontextFactory.eINSTANCE.createKey();
//		key.setName("project name");
//		
//		Value value = ExecutioncontextFactory.eINSTANCE.createValue();
//		value.setContent(project.getName());
//		
//		key.setValue(value);
//		value.setKey(key);
//		
//		executionContext.getKeys().add(key);
//		executionContext.getValues().add(value);
//		try {
//			resource.save(Collections.EMPTY_MAP);
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		
		return true;
	}

	public void setInitialProjectName(String value)
	{
		initialProjectName = value;
	}
}
